/*
 * Student.java - A simple class to represent a student at a university.
 * There's lots of information I could include here, but we are going to
 * restrict information to a name (first and last), a GPA, and a number
 * of credits earned.  The purpose here is to implement the compareTo
 * method defined in the Comparable interface, and then to use objects of
 * class student to test your generic tree.
 * 
 * I have provided set & get methods, a toString method, a constructor, and
 * an implementation of a method overriding Object's equals method.  You must
 * implement the compareTo method defined by the Comparable interface.  I have
 * provided a stub of this method for you to start with.  There is also a main
 * method with test code demonstrating the use of this class.
 */

package project2;

/**
 *
 * @author Michael R. Peterson (CS 202 Starter Code - Project 2 Spring 2009)
 */
public class Student implements Comparable<Student>  {
    
    // attributes
    private String lastName;
    private String firstName;
    private int credits;
    private double GPA;
    
    /**
     * Constructor to create a new Student
     * @param last last name.
     * @param first first name.
     * @param credits number of earned academic credits.
     * @param GPA Grade Point Average between 0.0 & 4.0
     */
    public Student(String last, String first, int credits, double GPA)
    {
        lastName = last;
        firstName = first;
        setCredits(credits);
        setGPA(GPA);
    }
    
    /**
     * ---------------------------------------------------------------------
     * TO DO: IMPLEMENT THIS METHOD
     * ---------------------------------------------------------------------
     * Compares this student to another student to determine an ordering
     * between students.  Ordering should be implemented as follows:
     * Students with more credits > students with less credits
     * If credits are tied between students:
     *      student with larger GPA > student with smaller GPA
     * If GPA is tied - compare last names, then first names (A less than Z)
     * This method must return 0 if the students are equal,
     * -1 if this student is "less than" student s, and
     * 1 if this student is "more than" student s in our ordering.
     * YOU MUST IMPLEMENT THIS METHOD IN ORDER TO PROPERLY INSERT STUDENT
     * OBJECTS INTO A BINARY TREE.
     * @param s A student to compare this student to.
     * @return 0 if students are equal, -1 if this student is smaller, 1 if larger.
     */
    public int compareTo(Student s) {
        if (credits > s.credits) {
            return 1;
        } else if (credits < s.credits) {
            return -1;
        } else {
            if (GPA > s.GPA) {
                return 1;
            } else if (GPA < s.GPA) {
                return -1;
            } else {
                if (lastName.toLowerCase().equals(s.lastName.toLowerCase())) {
                    if (firstName.toLowerCase().equals(s.firstName.toLowerCase())) {
                        return 0;
                    } else {
                        if (firstName.toLowerCase().charAt(0) > s.firstName.toLowerCase().charAt(0)) {
                            return 1;
                        } else {
                            return -1;
                        }
                    }
                } else {
                    if (lastName.toLowerCase().charAt(0) > s.lastName.toLowerCase().charAt(0)) {
                        return 1;
                    } else {
                        return -1;
                    }
                }
            }
        }
    }
    
    /**
     * Determine whether another object is an instance of Student with
     * the same attributes (first & last name, GPA, and earned credits).
     * @param obj  The object to compare to.
     * @return True if object is equal to this student, false otherwise.
     */
    public boolean equals(Object obj)
    {
        // first, make sure object is an instance of Student
        if(! (obj instanceof Student)) return false;
        // cast object to Student
        Student s = (Student) obj;
        // return true if they are equal
        return(lastName.equals(s.lastName) &&
               firstName.equals(s.firstName) &&
               credits == s.credits &&  // note: we can access private variables
               GPA == s.GPA); // in s because this code is in the Student class.
    }
    
    
    /**
     * Set the student's earned credits to the specified value (must be positive).
     * @param credits Number of credits earned.
     */
    public void setCredits(int credits)
    {
        if(credits < 0) credits = 0;
        this.credits = credits;
    }
    
    /**
     * Set the student's GPA to a value between 0.0 & 4.0 inclusive.
     * @param gpa The student's grade point average.
     */
    public void setGPA(double gpa)
    {
        if(gpa < 0.0) gpa = 0.0;
        if(gpa > 4.0) gpa = 4.0;
        this.GPA = gpa;
    }
    
    /**
     * Get the number of earned credits.
     * @return Student's earned credits.
     */
    public int getCredits()
    {
        return credits;
    }
    
    
    /**
     * Get the student's grade point average.
     * @return student's GPA.
     */
    public double getGPA()
    {
        return GPA;
    }
    
    /**
     * Get the student's first name.
     * @return Student's first name.
     */
    public String getFirstName()
    {
        return firstName;
    }
    
    /**
     * Get the student's last name.
     * @return Student's last name.
     */
    public String getLastName()
    {
        return lastName;
    }
    
    /**
     * Retrieve a string representation of the student.
     * @return string representation of student.
     */
    public String toString()
    {
        return new String(firstName + " " + lastName + " credits: " +
                credits + " " + "GPA: " + GPA);
    }

    /**
     * Test code for Student class
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        System.out.println("Student.java test code:");
        // Create two imaginary Students:
        Student s1 = new Student("Homer", "Simpson", 31, 2.06);
        Student s2 = new Student("Marge", "Simpson", 145, 3.25);
        
        System.out.println("Student s1: " + s1);
        System.out.println("Student s2: " + s2);
        System.out.println("S1 == S2? >> " + s1.equals(s2));
        
        System.out.println("Making s3 as a student with the same attributes as s1.");
        Student s3 = new Student("Homer", "Simpson", 31, 2.06);
        System.out.println("Student s3: " + s3);
        System.out.println("S1 == S3? >> " + s1.equals(s3));
        
        // test compare to method (should return -1 after you implement it)
        System.out.println("S1 compareTo S2? (should return -1) >> " + s1.compareTo(s2));
        System.out.println("S2 compareTo S1? (should return 1) >> " + s2.compareTo(s1));
        System.out.println("S1 compareTo S3? (should return 0) >> " + s1.compareTo(s3));
    }

}
